/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-08-15     liukang     the first version
 */

#include "utest.h"
#include <stdlib.h>
#include <aos/aos.h>
#include "aos/cli.h"

#define EVENT_FLAG3 (1 << 3)
#define EVENT_FLAG5 (1 << 5)

static aos_event_t dynamic_event = NULL;
static unsigned int dynamic_event_recv_thread_finish = 0, dynamic_event_send_thread_finish = 0;

static unsigned int recv_event_times1 = 0, recv_event_times2 = 0;
static unsigned int static_event_recv_thread_finish = 0, static_event_send_thread_finish = 0;

#define THREAD_PRIORITY      9
static unsigned int THREAD_STACK_SIZE = 2048;

static aos_task_t tid1 = NULL;
static aos_task_t tid2 = NULL;

static void test_event_create(void)
{
    signed long result = 0;
  
    result = aos_event_new(&dynamic_event,0x0);

    if (result != 0)
    {
        uassert_false(1);
    }

    aos_event_free(&dynamic_event);
    if (dynamic_event != NULL)
    {
        uassert_false(1);
    }

    uassert_true(1);
}

static void test_event_delete(void)
{
    signed long result;

   result = aos_event_new(&dynamic_event,0x0);
    if (dynamic_event == NULL)
    {
        uassert_false(1);
    }

    aos_event_free(&dynamic_event);

    if (dynamic_event != NULL)
    {
        uassert_false(1);
    }

    uassert_true(1);
}

static void thread1_recv_dynamic_event(void *param)
{
    unsigned int e;

    if(aos_event_get(&dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5),
                    AOS_EVENT_OR_CLEAR, &e, AOS_WAIT_FOREVER) != 0)                      
    {
        return;
    }

    recv_event_times1 = e;

    aos_msleep(50);

    if(aos_event_get(&dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5),
                    AOS_EVENT_AND_CLEAR, &e, AOS_WAIT_FOREVER) != 0) 
    {
        return;
    }
    recv_event_times2 = e;

    dynamic_event_recv_thread_finish = 1;
}

static void thread2_send_dynamic_event(void *param)
{
    aos_event_set(&dynamic_event, EVENT_FLAG3, 0);
    aos_msleep(10);

    aos_event_set(&dynamic_event, EVENT_FLAG5, 0);
    aos_msleep(10);

    aos_event_set(&dynamic_event, EVENT_FLAG3, 0);

    dynamic_event_send_thread_finish = 1;
}

static void test_dynamic_event_send_recv(void)
{
    signed long result;
    result = aos_event_new(&dynamic_event,0x0);
    if (dynamic_event == NULL)
    {
        uassert_false(1);
    }

    aos_task_create(&tid1,
                "tid1",
                thread1_recv_dynamic_event, NULL,
                NULL,
                THREAD_STACK_SIZE,
                THREAD_PRIORITY -1,
                AOS_TASK_AUTORUN);

    aos_task_create(&tid2,
                "tid2",
                thread2_send_dynamic_event, NULL,
                NULL,
                THREAD_STACK_SIZE,
                THREAD_PRIORITY,
                AOS_TASK_AUTORUN);

    while (dynamic_event_recv_thread_finish != 1 || dynamic_event_send_thread_finish != 1)
    {
        aos_msleep(1);
    }

    if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5))
    {
        aos_event_free(&dynamic_event);
        if (dynamic_event != NULL)
        {
            uassert_false(1);
        }
        uassert_true(1);
    }
    else
    {
        aos_event_free(&dynamic_event);
        if (dynamic_event != NULL)
        {
            uassert_false(1);
        }
    }

    return;
}


static signed long utest_tc_init(void)
{
    static_event_recv_thread_finish = 0;
    static_event_send_thread_finish = 0;
    dynamic_event_recv_thread_finish = 0;
    dynamic_event_send_thread_finish = 0;
    return 0;
}

static signed long utest_tc_cleanup(void)
{
    return 0;
}

static void testcase(void)
{
    UTEST_UNIT_RUN(test_event_create);
    UTEST_UNIT_RUN(test_event_delete);
    UTEST_UNIT_RUN(test_dynamic_event_send_recv);
}
UTEST_TC_EXPORT(testcase, "utest.example.event_tc", utest_tc_init, utest_tc_cleanup, 60);
